package DigitalNetwork;

import java.util.ArrayList;
import java.util.ListIterator;

/**
 * A digitalis halozat Composite epitoeleme.
 * <p>
 *
 * </p>
 *
 * @author Ableda Peter
 * @author Andrasi Istvan
 * @author Kamaras Karoly
 * @author Pora Szilard
 *
 * @version 1.0 Build 2011.04.17.
 */
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public class Composite extends Gate {

	/** Kompozit elem belso halozata. */
	private Network network;

	/** [Konstruktor]
	 * Letrehozza a be-,kimeneti listakat, ill. betolti a megvalositani kivant
	 * halozatot.
	 *
	 * @param ID_ A Composite elem neve.
	 * @param networkFile A megvalositott halozatot tartalmazo file
	 * @param x Az elem poziciojanak vizszintes komponense.
	 * @param y Az elem poziciojanak fuggoleges komponense.
	 */
	//==========================================================================
	public Composite(String ID_, String networkFile, int x, int y) {
		super(x, y);
		// Beallitjuk az ID-t.
		this.ID = ID_;
		// Letrehozzuk a bementi portok listajat.
		this.inputs = new ArrayList<PortIn>();
		// Letrehozzuk a kimenti portok listajat.
		this.outputs = new ArrayList<PortOut>();
		// Letrehozzuk a belso halozatot.
		this.network = new Network();
		if (this.network.loadNetwork(networkFile, true)) {

			// Letrehozzuk a megfelelo szamu bemenetet.
			for (int i = 0; i < this.network.simulator.getSourceCount(); i++) {
				this.inputs.add(new PortIn(this.ID + "_i" + i, this));
			}

			// Letrehozzuk a megfelelo szamu kimenetet.
			for (int i = 0; i < this.network.simulator.getDisplayCount(); i++) {
				this.outputs.add(new PortOut(this.ID + "_o" + i, this));
			}

			// Ertesitunk.
			Main.printMessage("#" + this.getID()
				+ " Composite elem letrehozva");
		} else {
			// Nem sikerult betoltenunk a belso halozatot.
			// Ertesitunk.
			Main.printMessage("#[HIBA] " + this.getID()
				+ " Composite elem betoltese sikertelen.");
		}
	}
	//==========================================================================

	/**
	 * A composit elem frissiti a kimenetet a belso mukodes szerint.
	 * 
	 */
	@Override
	//==========================================================================
	public void updateOutput() {

		// Egy itercaios lepest szimulalunk a belso halozaton.
		// A belso halozat jelforrasain a kompozit elem bemeneteinek
		// ertekeit adjuk ki.
		ListIterator<ISource> iS = network.simulator.sources.listIterator();
		ListIterator<PortIn> iI = this.inputs.listIterator();
		while (iS.hasNext() && iI.hasNext()) {
			ISource S = iS.next();
			PortIn P = iI.next();
			// Leptetjuk a belso jelforrast a megfelelo bemenet ertekevel.
			S.iterate(P.getState());
		}

		// Lekerdezzuk a belso halozat szimulaciojanak eredmenyet.
		// A kompozit elem kimeneteire a belso halozat kijelzoinek
		// ertekeit adjuk.
		ListIterator<IDisplay> iD = network.simulator.displays.listIterator();
		ListIterator<PortOut> iO = this.outputs.listIterator();
		while (iD.hasNext() && iO.hasNext()) {
			IDisplay D = iD.next();
			PortOut P = iO.next();
			// Kiadjuk a kimeneten a megfelelo belso kijelzo erteket.
			P.setState(D.getState());
		}

	}
	//==========================================================================

	/**
	 * Vissza adja az adott elem tipusat.
	 *
	 * @return String Az elem tipusa.
	 */
	@Override
	//==========================================================================
	public String getType() {
		return "Composite";
	}
	//==========================================================================
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

